from os import abort

from flask import render_template, session, current_app, request, jsonify, g

from info import constants, db
from info.models import News, Comment, CommentLike, User
from info.utils.captcha.response_code import RET
from info.utils.common import user_login_data
from . import news_blu

@news_blu.route('/<int:news_id>')
@user_login_data
def news_detail(news_id):
    '''
    新闻详情页
    :param news_id:
    :return:
    '''
    # 查询用户是否登录
    user=g.user

    # 显示右侧的排行
    news_list = []
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as r:
        current_app.logger.error(r)

    # 定义一个空的字典列表,里面存放字典

    news_dict_list = []
    for news in news_list:
        news_dict_list.append(news.to_dict())

    # 详情页数据是死的,需要从数据库里面查询书来数据,将其显示到前端
    news=None
    try:
        news=News.query.get(news_id)
    except Exception as r:
        current_app.logger.error(r)

    if not news:
        abort(404)

    # 更新新闻的点击次数
    news.clicks +=1

    # 设置一个变量,用来控制是否收藏
    is_collected=False

    '''
    判断用户是否收藏已经收藏
    1.判断用户是否已经登录 2.登录后判断用户是否收藏了该新闻
    '''
    if user:
        # 说明用户已经登录
        if news in user.collection_news:
            is_collected=True

    # 查询评论数据
    try:
        comments=Comment.query.filter(Comment.news_id==news_id).order_by(Comment.create_time.desc()).all()
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DATAERR, errmsg='数据查询错误')

    '''
    查询当前用户在新闻里面都点赞了那些评论
    
    1.查询出当前新闻的所有评论,取到所有的评论id
    2.在查询当前评论中那些评论被用户点赞CommentLike,查询comment_id
    在第一步的评论列表内的所有数据内的所有数据
    3.第二步查询出来是一个点赞的评论模型
    '''
    comment_like_ids=[]
    if g.user:
        # 1.查询出当前新闻的所有评论,取到所有的评论id
        comment_ids=[comment.id for comment in comments]
        # 2.在查询当前评论中那些评论被用户点赞CommentLike,查询comment_id
        # 在第一步的评论列表内的所有数据内的所有数据
        comment_likes=CommentLike.query.filter(CommentLike.comment_id.in_(comment_ids),CommentLike.user_id==g.user.id).all()
        print(comment_likes)
        # 取到所有点赞的id
        comment_like_ids=[comment_like.comment_id for comment_like in comment_likes]

    comment_dict_list=[]
    for comment in comments:
        comment_dict=comment.to_dict()
        comment_dict['is_like']=False

        if comment.id in comment_like_ids:
            comment_dict['is_like']=True
        comment_dict_list.append(comment_dict)

    is_followed=False
    if news.user and user:
        if news.user in user.followed:
            is_followed=True

    data={
        "user":user.to_dict() if user else None,
        "news_dict_list":news_dict_list,
        "news":news.to_dict(),
        "is_collected":is_collected,
        "comments":comment_dict_list,
        "is_followed":is_followed
    }

    return render_template('news/detail.html',data=data)

# 192.168.41.65

@news_blu.route('/news_collect',methods=['POST'])
@user_login_data
def news_collect():
    '''
    新闻收藏
    获取数据,校验数据
    :return:
    '''
    user=g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')
    # 接受参数
    news_id=request.json.get('news_id',None)
    action=request.json.get('action',None)
    # 判断参数
    if not all([news_id,action]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    if action not in ['collect','cancel_collect']:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    try:
        news_id=int(news_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')

    # 查询新闻,判断新闻是否存在
    try:
        news=News.query.get(news_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DATAERR,errmsg='数据查询错误')

    # 判断查询的新闻是否存在
    if not news:
        return jsonify(errno=RET.NODATA,errmsg='未查询到相关数据')
    # 收藏以及取消收藏
    # if news not in user.collection_news:
    #     user.collection_news.append(news)
    if action == 'collect':
        # 收藏
        if news not in user.collection_news:
            user.collection_news.append(news)
        else:
            return jsonify(errno=RET.OK,errmsg='已收藏')
    else:
        # 取消收藏
        if news in user.collection_news:
            user.collection_news.remove(news)

    return jsonify(errno=RET.OK,errmsg='操作成功')


# 新闻评论
@news_blu.route('/news_comment',methods=['POST'])
@user_login_data
def news_comment():
    '''
    评论新闻或者评论新闻下面的评论
    :return:
    '''
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')

    '''
    获取参数
    评论新闻,需要news_id,评论内容comment_content,评论主评论需要传入主评论id
    '''
    news_id=request.json.get('news_id',None)
    comment_content=request.json.get('comment_content',None)
    parent_id=request.json.get('parent_id',None)

    # 校验参数
    if not all([news_id,comment_content]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    try:
        news_id=int(news_id)
        if parent_id:
            parent_id=int(parent_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.PARAMERR, errmsg='参数格式错误')

    # 查询新闻,判断新闻是否存在
    try:
        news=News.query.get(news_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DATAERR, errmsg='数据查询错误')

    if not news:
        return jsonify(errno=RET.NODATA, errmsg='查不到该新闻')

    # 初始化评论模型
    comment=Comment()
    comment.user_id=user.id
    comment.news_id=news_id
    comment.content=comment_content
    if parent_id:
        comment.parent_id=parent_id

    # 由于在提交之前需要用到提交数据,所以不能用自动提交
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DATAERR, errmsg='数据提交失败')

    return jsonify(errno=RET.OK, errmsg='评论成功',data=comment.to_dict())


# 给评论点赞...
@news_blu.route('/comment_like',methods=['POST'])
@user_login_data
def comment_like():
    '''
    获取参数
    校验参数
    初始化评论模型
    :return:
    '''
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')

    # 获取请求参数
    comment_id=request.json.get('comment_id',None)
    news_id=request.json.get('news_id',None)
    # 是否点赞
    action=request.json.get('action',None)

    if not all([comment_id,news_id,action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ['add','remove']:
        return jsonify(errno=RET.PARAMERR, errmsg="参数格式错误")

    try:
        comment_id=int(comment_id)
        news_id=int(news_id)
    except Exception as r:
        return jsonify(errno=RET.PARAMERR, errmsg="参数格式错误")

    # 根据评论id找对应的comment模型
    try:
        comment=Comment.query.get(comment_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DATAERR, errmsg="数据查询错误")

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="未查询到相关数据")

    if action=='add':
        # 点赞:判断该用户对该评论是否点赞
        comment_like_model=CommentLike.query.filter(CommentLike.comment_id==comment_id,CommentLike.user_id==user.id).first()
        if not comment_like_model:
            # 若没有点赞,初始化CommentLike模型
            comment_like_model=CommentLike()
            comment_like_model.comment_id=comment_id
            comment_like_model.user_id=user.id
            db.session.add(comment_like_model)
            comment.like_count+=1
            print(comment.like_count)
    else:
        # 取消点赞
        comment_like_model = CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                                      CommentLike.user_id == user.id).first()
        if comment_like_model:
            # 如果已经点赞,取消点赞
            db.session.delete(comment_like_model)
            comment.like_count -= 1

    try:
        db.session.commit()
    except Exception as r:
        current_app.logger.error(r)
        db.session.rollback()
        return jsonify(errno=RET.DATAERR, errmsg="数据上传错误")

    return jsonify(errno=RET.OK, errmsg="点赞成功", data=comment.to_dict())

@news_blu.route('/followed_user',methods=['POST'])
@user_login_data
def followed_user():
    '''关注或者取消关注'''

    # 取到自己的登录信息
    user=g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg='用户未登录')


    user_id=request.json.get('user_id')
    action=request.json.get('action')

    if not all ([user_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg='PAR_ERROR')

    if action not in ['follow','unfollow']:
        return jsonify(errno=RET.PARAMERR, errmsg='PAR_ERROR')

    try:
        other=User.query.get(user_id)
    except Exception as r:
        current_app.logger.error(r)
        return jsonify(errno=RET.DBERR, errmsg='DB_ERROR')

    if not other:
        return jsonify(errno=RET.NODATA, errmsg='NO_ERROR')

    if action=='follow':
        if other not in user.followed:
            user.followed.append(other)
        else:
            return jsonify(errno=RET.DATAEXIST, errmsg='EXIST_ERROR')
    else:
        if other in user.followers:
            user.followed.remove(other)
        else:
            return jsonify(errno=RET.DATAEXIST, errmsg='EXIST_ERROR')

    return jsonify(errno=RET.OK, errmsg='OK')